from __future__ import absolute_import
from . import message
from scopt.util.message_types import INTEGER, STRING
from scopt.util import message as msg_util
from scopt.mpu.business.db import transaction
from sqlalchemy import asc, desc, and_


@message(type='inventory.item_search',
         version='0.1',
         reqd={'start': INTEGER(required=True),
               'count': INTEGER(required=True),
               'query': (),
               'sort': [STRING()]},
         resd={'items': [{'sku': STRING(required=True),
                          'name': STRING(required=True),
                          'qty': INTEGER(required=True),
                          'uom': STRING(required=True),
                          'uom_price': STRING(required=True)}],
               'total': INTEGER(required=True)})
@transaction(['lds/BDS'])
def handle(data_packet):
    request = msg_util.get_request(data_packet)
    sort = request['reqd']['sort']
    where = request['reqd']['query']
    db = msg_util.get_db(data_packet)
    products = db.table('m01_p')
    items = db.table('m01_i')

    response_data = []
    query = products.outerjoin(items).select()
#    query = products.outerjoin(items).select().\
#            where(where_clause(product, uom, where)).\
#            order_by(*sort_clause(product, uom, sort))
    for row in db.execute(query):
        record = {'sku': row['sku'],
                  'name': row['name']}
#        record = {'sku': row['sku'],
#                  'name': row['name'],
#                  'qty': row['qty'],
#                  'uom': row['desc_i18n'],
#                  'uom_price': "{0:.4f}".format(row['uom_price']/10000.0)}
        response_data.append(record)

    response = handle.RESPONSE()
    response['resh']['status'] = 'OK'
    response['resd']['items'] = response_data
    response['resd']['total'] = len(response_data)

    return msg_util.set_response(data_packet, response)


# TODO: methods are now obsolete. Use sqlalchemy methods instead
def _data_mapping(product, uom):
    return {'sku': product.c['sku'],
            'name': product.c['name'],
            'ssku': product.c['qty'],
            'qty': product.c['qty'],
            'uom': uom.c['desc_i18n'],
            'uom_price': product.c['uom_price']}


def where_clause(item, uom, where):
    if len(where) == 0:
        clause = 1 == 1
    else:
        conditions = [like_clause(item, uom, x, where[x])
                      for x in where.keys()]
        clause = and_(*conditions)
    return clause


def like_clause(item, uom, param_name, param_value):
    return _data_mapping(item, uom)[param_name].\
        like(param_value.replace('*', '%'))


def sort_clause(item, uom, sort):
    if len(sort) == 0:
        clause = [asc(item.c['sku'])]
    else:
        clause = [order(x[0])(_data_mapping(item, uom)[x[1:]]) for x in sort]
    return clause


def order(sign):
    if sign not in ('+', '-'):
        raise TypeError('Only + or - signs are allowed.')

    return asc if sign == '+' else desc
